package com.mdd.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.mdd.admin.config.quartz.QuartzUtils;
import com.mdd.admin.service.IIndexService;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.entity.Crontab;
import com.mdd.common.mapper.CrontabMapper;
import com.mdd.common.util.*;
import com.mdd.common.vo.MnpIndexVo;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 主页服务实现类
 */
@Service
public class IndexServiceImpl implements IIndexService {

    private static final String UPDATE_MENU_JOB_NAME = "myJob.updateMenu";

    @Resource
    Scheduler scheduler;

    @Resource
    CrontabMapper crontabMapper;

    /**
     * 控制台数据
     *
     * @author fzr
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> console() {
        Map<String, Object> console = new LinkedHashMap<>();

        // 版本信息
        Map<String, Object> version = new LinkedHashMap<>();
        version.put("name", ConfigUtils.get("website", "name", "LikeAdmin-Java"));
        version.put("version", GlobalConfig.version);
        version.put("website", "www.likeadmin.cn");
        version.put("based", "Vue3.x、ElementUI、MySQL");
        Map<String, String> channel = new LinkedHashMap<>();
        channel.put("gitee", "https://gitee.com/likeadmin/likeadmin_java");
        channel.put("website", "https://www.likeadmin.cn");
        version.put("channel", channel);
        console.put("version", version);

        // 今日数据
        Map<String, Object> today = new LinkedHashMap<>();
        today.put("time", "2022-08-11 15:08:29");
        today.put("todayVisits", 10);   // 访问量(人)
        today.put("totalVisits", 100);  // 总访问量
        today.put("todaySales", 30);    // 销售额(元)
        today.put("totalSales", 65);    // 总销售额
        today.put("todayOrder", 12);    // 订单量(笔)
        today.put("totalOrder", 255);   // 总订单量
        today.put("todayUsers", 120);   // 新增用户
        today.put("totalUsers", 360);   // 总访用户
        console.put("today", today);

        // 访客图表
        Map<String, Object> visitor = new LinkedHashMap<>();
        visitor.put("date", TimeUtils.daysAgoDate(15));
        visitor.put("list", Arrays.asList(12,13,11,5,8,22,14,9,456,62,78,12,18,22,46));
        console.put("visitor", visitor);

        return console;
    }

    /**
     * 公共配置
     *
     * @author fzr
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> config() {
        Map<String, String> website   = ConfigUtils.get("website");
        String copyright = ConfigUtils.get("website", "copyright", "");

        String captchaStatus = YmlUtils.get("like.captcha.status");

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("loginCaptcha", StringUtils.isNotNull(captchaStatus) && captchaStatus.equals("true"));
        map.put("webName", website.getOrDefault("name", ""));
        map.put("webLogo", UrlUtils.toAbsoluteUrl(website.getOrDefault("logo", "")));
        map.put("webFavicon", UrlUtils.toAbsoluteUrl(website.getOrDefault("favicon", "")));
        map.put("webBackdrop", UrlUtils.toAbsoluteUrl(website.getOrDefault("backdrop", "")));
        map.put("ossDomain", UrlUtils.domain());
        map.put("copyright", ArrayUtils.stringToListAsMapStr(copyright));

        return map;
    }

    @Override
    public Map<String, String> getMnpConfig() {
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("backgroundImg", ConfigUtils.get("mnp_config", "background_img"));
        resultMap.put("phone", ConfigUtils.get("mnp_config", "phone"));
        resultMap.put("notice", ConfigUtils.get("mnp_config", "notice"));
        resultMap.put("hasCamera", ConfigUtils.get("mnp_config", "has_camera"));
        resultMap.put("menuUpdateTime", ConfigUtils.get("mnp_config", "menu_update_time"));
        return resultMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void configMnp(Map<String, String> map) {
        ConfigUtils.set("mnp_config", "background_img", map.get("backgroundImg"));
        ConfigUtils.set("mnp_config", "phone", map.get("phone"));
        ConfigUtils.set("mnp_config", "notice", map.get("notice"));
        ConfigUtils.set("mnp_config", "has_camera", map.get("hasCamera"));

        // 菜单更新时间
        String menuUpdateTime = map.get("menuUpdateTime");
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date date = format.parse(menuUpdateTime);
            Calendar calendar = Calendar.getInstance();
            Calendar cal = Calendar.getInstance();
            calendar.setTime(date);
            cal.set(Calendar.HOUR, calendar.get(Calendar.HOUR));
            cal.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE));
            cal.set(Calendar.SECOND, calendar.get(Calendar.SECOND));
            String s = dateFormat.format(cal.getTime());
            this.setCrontab(CronUtil.createCronExpression(2, s));
        } catch (SchedulerException se) {
            throw ExceptionUtils.mpe("构建定时任务未创建", null);
        } catch (ParseException pe) {
            throw ExceptionUtils.mpe("时间格式不正确", null);
        } catch (Exception e) {
            throw ExceptionUtils.mpe(e.getMessage(), null);
        }
        ConfigUtils.set("mnp_config", "menu_update_time", menuUpdateTime);
    }

    private void setCrontab(String expression) throws SchedulerException {
        Crontab crontab = this.crontabMapper.selectOne(new QueryWrapper<Crontab>()
                .like("command", UPDATE_MENU_JOB_NAME + "%")
                .last("limit 1"));
        Assert.notNull(crontab, "定时任务未创建");
        crontab.setRules(expression);
        crontab.setUpdateTime(TimeUtils.timestamp());
        this.crontabMapper.updateById(crontab);

        QuartzUtils.createScheduleJob(scheduler, crontab);
    }
}
